import Speed2D from "../Movement/Speed2D";
import Point2D from "../Point/Point2D";
import Movement2D from "../Movement/Movement2D";
import Shape2D from "./Shape2D";

export default class PhysicalShape2D extends Shape2D {

    constructor(centre = new Point2D(0, 0), angle = 0, mass = 100) {
        super(centre, angle);
        this.mass = mass;
        this.movement = new Movement2D({speed: 0});
    }

    /**
     *
     * @param shape {PhysicalShape2D}
     */
    checkedCollided(shape) {
        if (!(shape instanceof PhysicalShape2D)) {
            super.checkedCollided(shape);
        } else {
            let thisAngle = this.getTouchLineFaceAngel(shape) + 90;
            let thatAngle = shape.getTouchLineFaceAngel(this) + 90;

            // 获取己方碰撞应该损失的动能
            let thisEK = this.getEK(thatAngle);
            // 获取对方碰撞应该损失的动能
            let thatEK = shape.getEK(thisAngle);


            // 己方损失动能
            this.applyEK(thisEK, thisAngle);
            // 对方损失动能
            shape.applyEK(thatEK, thatAngle);

            // 己方补充对方损失的动能
            this.applyEK(thatEK, thisAngle);
            // 对方补充己方损失的动能
            shape.applyEK(thisEK, thatAngle);


        }
    }

    /**
     * @param angle {number=}
     */
    getEK(angle) {
        if (angle == null) {
            return this.mass * Math.pow(this.movement.speed, 2) / 2;
        }
        let v = this.movement.speed * Math.cos((this.movement.angle - angle) * Math.PI / 180);
        if (v <= 0) {
            return -this.mass * Math.pow(v, 2) / 2;
        }
        return this.mass * Math.pow(v, 2) / 2;
    }

    /**
     * @param EK
     * @param angle {number=}
     */
    applyEK(EK, angle) {
        if (EK <= 0) {
            // 动能的减少
            let ownedEK = this.getEK();
            let resultEK = ownedEK + EK;
            let negativeAngle = false;
            if (resultEK < 0) {
                negativeAngle = true;
            }
            this.movement.speed = Math.sqrt(2 * Math.abs(resultEK) / this.mass);
            if (angle != null) {
                // 动能方向的改变
                this.movement.angle = angle - 90;
            }
            if (negativeAngle) {
                this.movement.angle += 180;
                this.movement.angle %= 360;
            }
        } else {
            // 动能的改变
            let v = Math.sqrt(2 * EK / this.mass);
            let speed = new Speed2D(v, angle);
            this.movement.speed2D.verticalSpeed += speed.verticalSpeed;
            this.movement.speed2D.horizontalSpeed += speed.horizontalSpeed;
        }
    }
}